package spring.superrun.tool.newid;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import spring.superrun.record.mvc.setup.JWTConfig;

import javax.validation.constraints.NotNull;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * JWT工具类
 * @author hby
 */
public class JwtUtils<ExpiredJwtException> {

    public static final long EXPIRATION_TIME = 3600; // 1 hour
    public static final String SECRET = "cL0@nA2(cA0*dB7[cG3^cF0)bC2_bC4+";//密码
    public static final String TOKEN_PREFIX = "Bearer";
    public static final String HEADER_STRING = "Authorization";
    public static final String Issuer = "superrun.server";//签发者
    public static final String Audience = "superrun.user";//被签发者
    /**
     签发对象：这个用户的id
     签发时间：现在
     有效时间：30分钟
     载荷内容：暂时设计为：这个人的id
     加密密钥：系统已定义
     */
    public static String createToken(String userId,String tokenType) {

        Calendar nowTime = Calendar.getInstance();
        nowTime.add(Calendar.MINUTE,60);//当前时间加60分钟
        if (!"".equals(tokenType)&&tokenType.equals(JWTConfig.AccessToken)){
            return JWT.create().withAudience(Audience)   //签发对象
                    .withIssuedAt(new Date())    //发行时间
                    .withExpiresAt(nowTime.getTime()) //有效时间
                    .withClaim(JWTConfig.TokenType,JWTConfig.AccessToken)//token类型
                    .withIssuer(Issuer)//Token颁发者
                    .withClaim(JWTConfig.Identification,userId)
                    .sign(Algorithm.HMAC256(SECRET));   //加密
        }
        if (!"".equals(tokenType)&&tokenType.equals(JWTConfig.RefreshToken)){
            return JWT.create().withAudience(Audience)   //签发对象
                    .withIssuedAt(new Date())    //发行时间
                    .withExpiresAt(new Date(System.currentTimeMillis()*1000
                            +360*24*7)) //有效时间 当前时间加7天的时间
                    .withClaim(JWTConfig.TokenType,JWTConfig.RefreshToken)//token类型
                    .withClaim(JWTConfig.Identification,userId)
                    .withIssuer(Issuer)//Token颁发者
                    .sign(Algorithm.HMAC256(SECRET));   //加密
        }
        return null;
    }

    /**
     * 检验合法性，其中secret参数就应该传入的是用户的id
     * @param token
     * @throws
     */
    public static boolean verifyToken(@NotNull String token) {
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET))
                .withIssuer(Issuer).build();
        try {
            DecodedJWT jwt = verifier.verify(token);
            return jwt!=null;
        } catch (JWTVerificationException e) {
            throw new RuntimeException("401");
        }
    }

    /**
     * 获取签发对象
     */
    public static String GetUserId(@NotNull String token) {
        try {
            String userId = JWT.decode(token)
                    .getClaim(JWTConfig.Identification).asString();
            return userId;
        } catch (JWTDecodeException j) {
            //这里是token解析失败
            //throw new GlobalHandleException(ResultCode.USER_AUTHENTICATION_ERROR);
            return null;
        }
    }

    /**
     * 获取Token类型
     * @param token
     * @return
     */
    public static String GetTokenType(@NotNull String token) {
        try {
            String tokenType = JWT.decode(token)
                    .getClaim(JWTConfig.TokenType).asString();
            return tokenType;
        } catch (JWTDecodeException j) {
            //这里是token解析失败
            //throw new GlobalHandleException(ResultCode.USER_AUTHENTICATION_ERROR);
            return null;
        }
    }
}
